/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.com.ecommerce.persistence;

import br.com.ecommerce.entity.IEntity;
import br.com.ecommerce.persistence.exception.DAOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ejb.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

/**
 *
 * @author rpateixeira
 */
@Singleton
public class CrudPersistence {

    @PersistenceContext
    private EntityManager em;

    public <T> List<T> find(String query,Map<String,Object> params){
        Query myQuery= createQuery(query, params);
        return myQuery.getResultList();
    }
    public <T> List<T> find(String query,Map<String,Object> params,int limit){
        Query myQuery= createQuery(query, params);
        myQuery.setMaxResults(limit);
        return myQuery.getResultList();
    }
    public <T> List<T> findByNamed(String namedQuery,Map<String,Object> params){
        Query query=em.createNamedQuery(namedQuery);
        setParameters(query, params);
        return query.getResultList();
    }
    private Query createQuery(String query,Map<String,Object> params){
        Query myQuery=em.createQuery(query);
        setParameters(myQuery, params);
        return myQuery;
    }
    private void setParameters(Query query,Map<String,Object> params){
        if(params!=null && !params.isEmpty()){
            Set<String> keys=params.keySet();
            for (String key : keys) {
                query.setParameter(key, params.get(key));
            }
        }
    }
    public <T> T getPojo(String query,Map<String,Object> params){
        Query qr=createQuery(query, params);
        return (T) qr.getSingleResult();
    }
    public <T> T getPojo(Class<T> entity,Long id){
        return em.find(entity, id);
    }
    public <T extends IEntity> T insert(T entity)  {
        if(entity!=null &&entity.getId()==null){
    	  try{
    	    em.persist(entity);
    	    return entity;
    	  }catch(PersistenceException e) {
    	    throw new DAOException("Não foi possivel inserir na base de dados",e);
    	  }
    	}
        throw new DAOException("Entidade com identificador NULL");
    }
    public <T extends IEntity> T update(T entity) {
       if(entity!=null &&entity.getId()!=null){
          try{
             return em.merge(entity);
    	  }catch(PersistenceException e){
		throw new DAOException("Erro ao Atualizar Entidade",e);
          }
       }
       throw new DAOException("updateCRUDidNULL");
    }
    public <T extends IEntity> void remove(T entity)  {
       if(entity!=null &&entity.getId()!=null){
	try{
 	  em.remove(em.merge(entity));
	}catch(PersistenceException re){
	   throw new DAOException("Erro ao remover Entidade",re);
        }
       }else{
          throw new DAOException("Erro ao remover Entidade Objeto NUll ou idNUll");
        }
    }

    public <T extends IEntity> void refresh(T entity) {
        em.refresh(entity);
    }
}
